﻿Imports System.Web

Namespace DotNetNuke.Modules.ActiveForums
    Public Class ForumsReWriter
        Implements IHttpModule
        Private _forumgroupId As Integer = -1
        Private _forumId As Integer = -1
        Private _tabId As Integer = -1
        Private _moduleId As Integer = -1
        Private _topicId As Integer = -1
        Private _page As Integer = 1
        Private _contentId As Integer = -1
        Private _userId As Integer = -1
        Private _archived As Integer = 0
        Private _mainSettings As SettingsInfo = Nothing
        Private _urlType As Integer = 0 '0=default, 1= views, 2 = category, 3 = tag
        Private _otherId As Integer = -1
        Private _categoryId As Integer = -1
        Private _tagId As Integer = -1
        Public Sub Dispose() Implements System.Web.IHttpModule.Dispose

        End Sub

        Public Sub Init(ByVal context As System.Web.HttpApplication) Implements System.Web.IHttpModule.Init
            AddHandler context.BeginRequest, AddressOf OnBeginRequest
        End Sub
        Public Sub OnBeginRequest(ByVal s As Object, ByVal e As EventArgs)
            _forumId = -1
            _tabId = -1
            _moduleId = -1
            _topicId = -1
            _page = 1
            _contentId = -1
            _archived = 0
            _forumgroupId = -1
            _mainSettings = Nothing
            _categoryId = -1
            _tagId = -1

            Dim app As HttpApplication = CType(s, HttpApplication)
            Dim Server As HttpServerUtility = app.Server
            Dim Request As HttpRequest = app.Request
            Dim Response As HttpResponse = app.Response
            Dim requestedPath As String = app.Request.Url.AbsoluteUri
            Dim Context As HttpContext = CType(s, HttpApplication).Context
            Dim PortalId As Integer = -1
            Dim objPortalAliasInfo As DotNetNuke.Entities.Portals.PortalAliasInfo = Nothing
            Dim sUrl As String = HttpContext.Current.Request.RawUrl.Replace("http://", String.Empty).Replace("https://", String.Empty)
            objPortalAliasInfo = DotNetNuke.Entities.Portals.PortalSettings.GetPortalAliasInfo(HttpContext.Current.Request.Url.Host)
            If Request.RawUrl.ToLowerInvariant.Contains("404.aspx") Then
                Dim sEx As String = ".jpg,.gif,.png,.swf,.js,.css,.html,.htm,desktopmodules,portals,.ashx,.ico,.txt,.doc,.docx,.pdf,.xml,.xls,.xlsx,.ppt,.pptx,.csv,.zip,.asmx,.aspx"
                For Each sn As String In sEx.Split(CChar(","))
                    If sUrl.Contains(sn) Then
                        ' IO.File.AppendAllText(sPath, Request.RawUrl & "165<br />")
                        Exit Sub
                    End If
                Next
            End If
            If Request.Url.LocalPath.ToLower.Contains("scriptresource.axd") _
                   OrElse Request.Url.LocalPath.ToLower.Contains("webresource.axd") _
                   OrElse Request.Url.LocalPath.ToLower.Contains("viewer.aspx") _
                   OrElse Request.Url.LocalPath.ToLower.Contains("cb.aspx") _
                   OrElse Request.Url.LocalPath.ToLower.Contains("filesupload.aspx") _
                   OrElse Request.Url.LocalPath.ToLower.Contains(".gif") _
                   OrElse Request.Url.LocalPath.ToLower.Contains(".jpg") _
                   OrElse Request.Url.LocalPath.ToLower.Contains(".css") _
                   OrElse Request.Url.LocalPath.ToLower.Contains(".png") _
                   OrElse Request.Url.LocalPath.ToLower.Contains(".swf") _
                   OrElse Request.Url.LocalPath.ToLower.Contains(".htm") _
                   OrElse Request.Url.LocalPath.ToLower.Contains(".html") _
                   OrElse Request.Url.LocalPath.ToLower.Contains(".ashx") _
                   OrElse Request.Url.LocalPath.ToLower.Contains(".cur") _
                   OrElse Request.Url.LocalPath.ToLower.Contains(".ico") _
                   OrElse Request.Url.LocalPath.ToLower.Contains(".txt") _
                   OrElse Request.Url.LocalPath.ToLower.Contains(".pdf") _
                    OrElse Request.Url.LocalPath.ToLower.Contains(".xml") _
                    OrElse Request.Url.LocalPath.ToLower.Contains("/portals/") _
                    OrElse Request.Url.LocalPath.ToLower.Contains("/desktopmodules/") _
                   OrElse Request.Url.LocalPath.ToLower.Contains("evexport.aspx") _
                   OrElse Request.Url.LocalPath.ToLower.Contains("signupjs.aspx") _
                   OrElse Request.Url.LocalPath.ToLower.Contains("evsexport.aspx") _
                   OrElse Request.Url.LocalPath.ToLower.Contains("fbcomm.aspx") _
                   OrElse Request.Url.LocalPath.ToLower.Contains(".aspx") _
                   OrElse Request.Url.LocalPath.ToLower.Contains(".js") Then
                Exit Sub
            End If
            If Request.Url.LocalPath.ToLower.Contains("install.aspx") _
                   OrElse Request.Url.LocalPath.ToLower.Contains("installwizard.aspx") _
                   OrElse Request.Url.LocalPath.ToLower.Contains("captcha.aspx") _
                   OrElse Request.RawUrl.Contains("viewer.aspx") _
                   OrElse Request.RawUrl.Contains("blank.html") _
                   OrElse Request.RawUrl.Contains("default.htm") _
                   OrElse Request.RawUrl.Contains("autosuggest.aspx") Then
                Exit Sub
            End If
            PortalId = objPortalAliasInfo.PortalID
            Dim searchURL As String = sUrl
            searchURL = searchURL.Replace(objPortalAliasInfo.HTTPAlias, String.Empty)
            If searchURL.Length < 2 Then
                Exit Sub
            End If
            Dim query As String = String.Empty
            If searchURL.Contains("?") Then
                query = searchURL.Substring(searchURL.IndexOf("?"))
                searchURL = searchURL.Substring(0, searchURL.IndexOf("?") - 1)
            End If
            Dim newSearchURL As String = String.Empty
            For Each up As String In searchURL.Split(CChar("/"))
                If Not String.IsNullOrEmpty(up) Then
                    If Not IsNumeric(up) Then
                        newSearchURL &= up & "/"
                    End If
                End If
            Next
            Dim canContinue As Boolean = False
            Dim db As New Data.Common
            Dim tagName As String = String.Empty
            Dim catName As String = String.Empty
            If newSearchURL.Contains("/category/") Or newSearchURL.Contains("/tag/") Then
                If newSearchURL.Contains("/category/") Then
                    Dim cat As String = "/category/"
                    Dim iEnd As Integer = newSearchURL.IndexOf("/", newSearchURL.IndexOf(cat) + cat.Length + 1)
                    Dim catString As String = newSearchURL.Substring(newSearchURL.IndexOf(cat), iEnd - newSearchURL.IndexOf(cat))
                    catName = catString.Replace(cat, String.Empty)
                    catName = catName.Replace("/", String.Empty)
                    newSearchURL = newSearchURL.Replace(catString, String.Empty)
                End If
                If newSearchURL.Contains("/tag/") Then
                    Dim tag As String = "/tag/"
                    Dim iEnd As Integer = newSearchURL.IndexOf("/", newSearchURL.IndexOf(tag) + tag.Length + 1)
                    Dim tagString As String = newSearchURL.Substring(newSearchURL.IndexOf(tag), iEnd - newSearchURL.IndexOf(tag))
                    tagName = tagString.Replace(tag, String.Empty)
                    tagName = tagName.Replace("/", String.Empty)
                    newSearchURL = newSearchURL.Replace(tagString, String.Empty)
                End If
            End If
            If (sUrl.Contains("afv") And sUrl.Contains("post")) Or _
                (sUrl.Contains("afv") And sUrl.Contains("confirmaction")) Or _
                (sUrl.Contains("afv") And sUrl.Contains("sendto")) Or _
                (sUrl.Contains("afv") And sUrl.Contains("modreport")) Or _
                (sUrl.Contains("afv") And sUrl.Contains("search")) Or _
                sUrl.Contains("dnnprintmode") Or _
                sUrl.Contains("asg") Or _
                (sUrl.Contains("afv") And sUrl.Contains("modtopics")) Then
                Exit Sub
            End If
            Try
                Using dr As IDataReader = db.URLSearch(PortalId, newSearchURL)
                    While dr.Read()
                        _tabId = Integer.Parse(dr("TabID").ToString)
                        _moduleId = Integer.Parse(dr("ModuleId").ToString)
                        _forumgroupId = Integer.Parse(dr("ForumGroupId").ToString)
                        _forumId = Integer.Parse(dr("ForumId").ToString)
                        _topicId = Integer.Parse(dr("TopicId").ToString)
                        _archived = Integer.Parse(dr("Archived").ToString)
                        _otherId = Integer.Parse(dr("OtherId").ToString)
                        _urlType = Integer.Parse(dr("UrlType").ToString)
                        canContinue = True
                    End While
                    dr.Close()
                End Using
            Catch ex As Exception

            End Try
            If Not String.IsNullOrEmpty(catName) Then
                _categoryId = db.Tag_GetIdByName(PortalId, _moduleId, catName, True)
                _otherId = _categoryId
                _urlType = 2
            End If
            If Not String.IsNullOrEmpty(tagName) Then
                _tagId = db.Tag_GetIdByName(PortalId, _moduleId, tagName, False)
                _otherId = _tagId
                _urlType = 3
            End If

            If _archived = 1 Then
                sUrl = db.GetUrl(_moduleId, _forumgroupId, _forumId, _topicId, _userId, -1)
                If Not String.IsNullOrEmpty(sUrl) Then
                    Dim sHost As String = objPortalAliasInfo.HTTPAlias
                    If sUrl.StartsWith("/") Then
                        sUrl = sUrl.Substring(1)
                    End If
                    If Not sHost.EndsWith("/") Then
                        sHost &= "/"
                    End If
                    sUrl = sHost & sUrl
                    If Not sUrl.EndsWith("/") Then
                        sUrl &= "/"
                    End If
                    If Not sUrl.StartsWith("http") Then
                        If Request.IsSecureConnection Then
                            sUrl = "https://" & sUrl
                        Else
                            sUrl = "http://" & sUrl
                        End If
                    End If
                    Response.Clear()
                    Response.Status = "301 Moved Permanently"
                    Response.AddHeader("Location", sUrl)
                    Response.End()

                End If
            End If
            If _moduleId > 0 Then
                Dim objModules As New Entities.Modules.ModuleController
                Dim objSettings As New SettingsInfo
                objSettings.MainSettings = objModules.GetModuleSettings(_moduleId)
                _mainSettings = objSettings ' DataCache.MainSettings(_moduleId)
            End If
            If _mainSettings Is Nothing Then
                Exit Sub
            End If
            If Not _mainSettings.URLRewriteEnabled Then
                Exit Sub
            End If
            If Not canContinue And (Request.RawUrl.Contains(ParamKeys.TopicId) Or Request.RawUrl.Contains(ParamKeys.ForumId) Or Request.RawUrl.Contains(ParamKeys.GroupId)) Then
                sUrl = HandleOldUrls(Request.RawUrl, objPortalAliasInfo.HTTPAlias)
                If Not String.IsNullOrEmpty(sUrl) Then
                    If Not sUrl.StartsWith("http") Then
                        If Request.IsSecureConnection Then
                            sUrl = "https://" & sUrl
                        Else
                            sUrl = "http://" & sUrl
                        End If
                    End If
                    Response.Clear()
                    Response.Status = "301 Moved Permanently"
                    Response.AddHeader("Location", sUrl)
                    Response.End()
                End If
            End If
            If Not canContinue Then
                Dim topicUrl As String = String.Empty
                If newSearchURL.EndsWith("/") Then
                    newSearchURL = newSearchURL.Substring(0, newSearchURL.Length - 1)
                End If
                If newSearchURL.Contains("/") Then
                    topicUrl = newSearchURL.Substring(newSearchURL.LastIndexOf("/"))
                End If
                topicUrl = topicUrl.Replace("/", String.Empty)
                If Not String.IsNullOrEmpty(topicUrl) Then
                    Dim topicsDb As New Data.Topics
                    _topicId = topicsDb.TopicIdByUrl(PortalId, _moduleId, topicUrl.ToLowerInvariant)
                    If _topicId > 0 Then
                        sUrl = db.GetUrl(_moduleId, _forumgroupId, _forumId, _topicId, _userId, -1)
                    Else
                        sUrl = String.Empty
                    End If
                    If Not String.IsNullOrEmpty(sUrl) Then
                        Dim sHost As String = objPortalAliasInfo.HTTPAlias
                        If sHost.EndsWith("/") And sUrl.StartsWith("/") Then
                            sUrl = sHost.Substring(0, sHost.Length - 1) & sUrl
                        ElseIf Not sHost.EndsWith("/") And Not sUrl.StartsWith("/") Then
                            sUrl = sHost & "/" & sUrl
                        Else
                            sUrl = sHost & sUrl
                        End If
                        If sUrl.StartsWith("/") Then
                            sUrl = sUrl.Substring(1)
                        End If
                        If Not sUrl.StartsWith("http") Then
                            If Request.IsSecureConnection Then
                                sUrl = "https://" & sUrl
                            Else
                                sUrl = "http://" & sUrl
                            End If
                        End If
                        If Not String.IsNullOrEmpty(sUrl) Then
                            Response.Clear()
                            Response.Status = "301 Moved Permanently"
                            Response.AddHeader("Location", sUrl)
                            Response.End()
                        End If
                    End If
                End If

            End If

            If canContinue Then
                If searchURL <> newSearchURL Then
                    Dim urlTail As String = searchURL.Replace(newSearchURL, String.Empty)
                    If urlTail.StartsWith("/") Then
                        urlTail = urlTail.Substring(1)
                    End If
                    If urlTail.EndsWith("/") Then
                        urlTail = urlTail.Substring(0, urlTail.Length - 1)
                    End If
                    If urlTail.Contains("/") Then
                        urlTail = urlTail.Substring(0, urlTail.IndexOf("/") - 1)
                    End If
                    If IsNumeric(urlTail) Then
                        _page = CInt(urlTail)
                    End If
                End If

                Dim sPage As String = String.Empty
                sPage = "&afpg=" & _page.ToString
                Dim qs As String = String.Empty
                If sUrl.Contains("?") Then
                    qs = "&" & sUrl.Substring(sUrl.IndexOf("?") + 1)
                End If
                Dim catQS As String = String.Empty
                If _categoryId > 0 Then
                    catQS = "&act=" & _categoryId.ToString
                End If
                Dim sendTo As String = String.Empty
                If _topicId > 0 Then
                    sendTo = ResolveUrl(app.Context.Request.ApplicationPath, "~/default.aspx?tabid=" & _tabId & "&aft=" & _topicId & sPage & qs)
                ElseIf _forumId > 0 Then
                    sendTo = ResolveUrl(app.Context.Request.ApplicationPath, "~/default.aspx?tabid=" & _tabId & "&aff=" & _forumId & sPage & qs & catQS)
                ElseIf _forumgroupId > 0 Then
                    sendTo = ResolveUrl(app.Context.Request.ApplicationPath, "~/default.aspx?tabid=" & _tabId & "&afg=" & _forumgroupId & sPage & qs & catQS)
                ElseIf _urlType = 2 And _otherId > 0 Then
                    sendTo = ResolveUrl(app.Context.Request.ApplicationPath, "~/default.aspx?tabid=" & _tabId & "&act=" & _otherId & sPage & qs)
                ElseIf _urlType = 3 And _otherId > 0 Then
                    sendTo = ResolveUrl(app.Context.Request.ApplicationPath, "~/default.aspx?tabid=" & _tabId & "&afv=grid&afgt=tags&aftg=" & _otherId & sPage & qs)
                ElseIf _urlType = 1 Then
                    Dim v As String = String.Empty
                    Select Case _otherId
                        Case 1
                            v = "unanswered"
                        Case 2
                            v = "notread"
                        Case 3
                            v = "mytopics"
                        Case 4
                            v = "activetopics"
                    End Select
                    sendTo = ResolveUrl(app.Context.Request.ApplicationPath, "~/default.aspx?tabid=" & _tabId & "&afv=grid&afgt=" & v & sPage & qs)
                ElseIf _tabId > 0 Then
                    sendTo = ResolveUrl(app.Context.Request.ApplicationPath, "~/default.aspx?tabid=" & _tabId & sPage & qs)
                End If

                RewriteUrl(app.Context, sendTo)
            End If
        End Sub
        Friend Shared Function ResolveUrl(ByVal appPath As String, ByVal url As String) As String

            ' String is Empty, just return Url
            If (url.Length = 0) Then
                Return url
            End If

            ' String does not contain a ~, so just return Url
            If (url.StartsWith("~") = False) Then
                Return url
            End If

            ' There is just the ~ in the Url, return the appPath
            If (url.Length = 1) Then
                Return appPath
            End If

            If (url.ToCharArray()(1) = "/" Or url.ToCharArray()(1) = "\") Then
                ' Url looks like ~/ or ~\
                If (appPath.Length > 1) Then
                    Return appPath + "/" & url.Substring(2)
                Else
                    Return "/" & url.Substring(2)
                End If
            Else
                ' Url look like ~something
                If (appPath.Length > 1) Then
                    Return appPath & "/" & url.Substring(1)
                Else
                    Return appPath & url.Substring(1)
                End If
            End If

        End Function
        Friend Shared Sub RewriteUrl(ByVal context As HttpContext, ByVal sendToUrl As String)
            Dim x As String = ""
            Dim y As String = ""

            RewriteUrl(context, sendToUrl, x, y)
        End Sub

        Friend Shared Sub RewriteUrl(ByVal context As HttpContext, ByVal sendToUrl As String, ByRef sendToUrlLessQString As String, ByRef filePath As String)

            ' first strip the querystring, if any
            Dim queryString As String = String.Empty
            sendToUrlLessQString = sendToUrl

            If (sendToUrl.IndexOf("?") > 0) Then
                sendToUrlLessQString = sendToUrl.Substring(0, sendToUrl.IndexOf("?"))
                queryString = sendToUrl.Substring(sendToUrl.IndexOf("?") + 1)
            End If

            ' grab the file's physical path
            filePath = String.Empty
            filePath = context.Server.MapPath(sendToUrlLessQString)

            ' rewrite the path..
            If sendToUrlLessQString.Contains("/404.aspx?404;") Then
                sendToUrlLessQString = sendToUrlLessQString.Substring(sendToUrlLessQString.IndexOf("/404.aspx?404;") + 14)

            End If
            context.RewritePath(sendToUrlLessQString, String.Empty, queryString)

            ' NOTE!  The above RewritePath() overload is only supported in the .NET Framework 1.1
            ' If you are using .NET Framework 1.0, use the below form instead:
            ' context.RewritePath(sendToUrl);

        End Sub
        Private Function HandleOldUrls(ByVal rawUrl As String, ByVal httpAlias As String) As String
            Dim sUrl As String = String.Empty
            Dim currURL As String = rawUrl
            Dim splitter As String = "/"
            If currURL.Contains("&") Then
                splitter = "&"
            End If
            Dim parts() As String = currURL.Split(CChar(splitter))
            For i As Integer = 0 To parts.Length - 1
                If Not String.IsNullOrEmpty(parts(i)) Then
                    If parts(i).ToLowerInvariant.Contains("=") Then
                        Dim pair() As String = parts(i).Split(CChar("="))
                        If pair(0).ToLowerInvariant = ParamKeys.ForumId Then
                            _forumId = Integer.Parse(pair(1))
                        ElseIf pair(0).ToLowerInvariant = ParamKeys.TopicId Then
                            _topicId = Integer.Parse(pair(1))
                        ElseIf pair(0).ToLowerInvariant = ParamKeys.PageId Then
                            _page = Integer.Parse(pair(1))
                        ElseIf pair(0).ToLowerInvariant = ParamKeys.PageJumpId Then
                            _page = Integer.Parse(pair(1))
                        ElseIf pair(0).ToLowerInvariant = ParamKeys.ContentJumpId Then
                            _contentId = Integer.Parse(pair(1))
                        End If
                    Else
                        If parts(i).ToLowerInvariant = ParamKeys.ForumId Then
                            _forumId = Integer.Parse(parts(i + 1))
                        ElseIf parts(i).ToLowerInvariant = ParamKeys.TopicId Then
                            _topicId = Integer.Parse(parts(i + 1))
                        ElseIf parts(i).ToLowerInvariant = ParamKeys.PageId Then
                            _page = Integer.Parse(parts(i + 1))
                        ElseIf parts(i).ToLowerInvariant = ParamKeys.PageJumpId Then
                            _page = Integer.Parse(parts(i + 1))
                        ElseIf parts(i).ToLowerInvariant = "tabid" Then
                            _tabId = Integer.Parse(parts(i + 1))
                        ElseIf parts(i).ToLowerInvariant = ParamKeys.ContentJumpId Then
                            _contentId = Integer.Parse(parts(i + 1))
                        End If
                    End If
                End If
            Next
            Dim db As New Data.Common
            sUrl = db.GetUrl(_moduleId, _forumgroupId, _forumId, _topicId, _userId, _contentId)
            If Not String.IsNullOrEmpty(sUrl) Then

                Dim sHost As String = httpAlias
                If sUrl.StartsWith("/") Then
                    sUrl = sUrl.Substring(1)
                End If

                If Not sHost.EndsWith("/") Then
                    sHost &= "/"
                End If
                sUrl = sHost & sUrl
                If Not sUrl.EndsWith("/") Then
                    sUrl &= "/"
                End If
                If _contentId > 0 Then
                    If _page > 1 Then
                        sUrl &= _page & "/"
                    End If
                End If


            End If
            Return sUrl
        End Function
    End Class
End Namespace

